package com.liwenfeng.huangputi;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/*
 * 某企业有100名员工，工号依次是1-100。现公司举办年会，有一个发红包环节，要求：
 *     共发200个红包，其中小红包[1-30]元占80%，大红包[31-100]元，占20%。
 * 系统模拟产生200个红包
 * 模拟100个员工抢红包，输出哪个员工抢到哪个红包的过程，活动结束给出提示；
 * 对100名员工按红包金额降序排序，输出到控制台
 *
 * 多线程方法实现
 * */
public class HongBaoYuGameThread {
    HashMap<Integer, List<Integer>> map = new HashMap<>();
    ArrayList<Integer> redPackets = new ArrayList<>();
    Random random = new Random();

    {
        //生成160个小红包，40个大红包，初始化员工列表
        for (int i = 0; i < 160; i++) {
            redPackets.add(random.nextInt(1, 31));
            if (i < 40) redPackets.add(random.nextInt(31, 101));
            if (i < 100) map.put(i + 1, new ArrayList<>());
        }
        Collections.shuffle(redPackets);
        System.out.println("生成红包：" + redPackets + "共" + redPackets.size() + "个红包");
    }

    public void redWars() {
        ArrayList<CompletableFuture<Void>> futures = new ArrayList<>();
        ExecutorService pool = Executors.newFixedThreadPool(100);
        for (Integer integer : map.keySet()) {
            futures.add(CompletableFuture.runAsync(() -> {
                while (true) {
                    synchronized (this) {
                        this.notify();
                        if (redPackets.size() == 0) break;
                        Integer packet = redPackets.remove(redPackets.size()-1);
                        System.out.println(integer + "号员工抢到红包：" + packet + "元");
                        map.get(integer).add(packet);
                        try {
                            this.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }, pool));
        }
        for (CompletableFuture<Void> future : futures) {
            try {
                future.get();
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
        pool.close();
        System.out.println("抢红包结束了...");
    }

    public static void main(String[] args) {

        HongBaoYuGameThread hongBaoYuGame = new HongBaoYuGameThread();

        hongBaoYuGame.redWars();
        System.out.println(hongBaoYuGame.map);
        System.out.println("按金额降序排序：------------------");
        hongBaoYuGame.map.entrySet().stream()
                .map(item -> Map.entry(item.getKey(), item.getValue().stream().reduce(0, Integer::sum)))
                .sorted((o1, o2) -> o2.getValue() - o1.getValue()).forEach(System.out::println);

    }
}
